<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge" ><![endif]-->
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Inflate/deflate, URL encode/decode</title>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
  <script type="text/javascript" src="deflate/pako.min.js"></script>
<script type="text/javascript">
//<![CDATA[
function stringToBytes(str)
{
    var arr = new Array(str.length);

    for (var i = 0; i < str.length; i++)
    {
        arr[i] = str.charCodeAt(i);
    }

    return arr;
};

function bytesToString(arr)
{
    var str = '';

    for (var i = 0; i < arr.length; i++)
    {
        str += String.fromCharCode(arr[i]);
    }

    return str;
};

function encode(data)
{
    if (document.getElementById('encodeCheckbox').checked)
    {
        try
        {
            data = encodeURIComponent(data);
        }
        catch (e)
        {
            console.log(e);
            alert('encodeURIComponent failed: ' + e);

            return;
        }
    }

    if (document.getElementById('deflateCheckbox').checked && data.length > 0)
    {
		try
        {
        	data = bytesToString(pako.deflateRaw(data));
        }
        catch (e)
        {
            console.log(e);
            alert('deflateRaw failed: ' + e);

            return;
        }
    }

    if (document.getElementById('base64Checkbox').checked)
    {
    	try
    	{
        	data = btoa(data);
        }
        catch (e)
        {
            console.log(e);
            alert('atob failed: ' + e);

            return;
        }
    }

	if (data.length > 0)
	{
    	document.getElementById('textarea').value = data;
    }
};

function removeLinebreaks(data)
{
    document.getElementById('textarea').value = data.replace(/(\r\n|\n|\r)/gm, '');
};

function decode(data)
{
    try
    {
        var node = parseXml(data).documentElement;

        if (node != null && node.nodeName == 'mxfile')
        {
            var diagrams = node.getElementsByTagName('diagram');

            if (diagrams.length > 0)
            {
                data = getTextContent(diagrams[0]);
            }
        }
    }
    catch (e)
    {
        // ignore
    }

    if (document.getElementById('base64Checkbox').checked)
    {
        try
        {
            data = atob(data);
        }
        catch (e)
        {
            console.log(e);
            alert('atob failed: ' + e);

            return;
        }
    }

    if (document.getElementById('deflateCheckbox').checked && data.length > 0)
    {
        try
        {
            data = bytesToString(pako.inflateRaw(data));
        }
        catch (e)
        {
            console.log(e);
            alert('inflateRaw failed: ' + e);

            return;
        }
    }

    if (document.getElementById('encodeCheckbox').checked)
    {
        try
        {
            data = decodeURIComponent(data);
        }
        catch (e)
        {
            console.log(e);
            alert('decodeURIComponent failed: ' + e);

            return;
        }
    }

	if (data.length > 0)
	{
    	document.getElementById('textarea').value = data;
    }
};

function parseXml(xml)
{
    if (window.DOMParser)
    {
        var parser = new DOMParser();

        return parser.parseFromString(xml, 'text/xml');
    }
    else
    {
        var result = createXmlDocument();

        result.async = 'false';
        result.loadXML(xml);

        return result;
    }
};

function createXmlDocument()
{
    var doc = null;

    if (document.implementation && document.implementation.createDocument)
    {
        doc = document.implementation.createDocument('', '', null);
    }
    else if (window.ActiveXObject)
    {
        doc = new ActiveXObject('Microsoft.XMLDOM');
    }

    return doc;
};

function decodeFromUri()
{
    try
    {
        document.getElementById('textarea').value = decodeURIComponent(document.getElementById('textarea').value)
    }
	catch (e)
	{
		console.log(e);
		alert('decodeURIComponent failed: ' + e);
    }
};

function getTextContent(node)
{
    return (node != null) ? node[(node.textContent === undefined) ? 'text' : 'textContent'] : '';
};

function normalizeXml()
{
  try
  {
    var str = document.getElementById('textarea').value;
    str = str.replace(/>\s*/g, '>');  // Replace "> " with ">"
    str = str.replace(/\s*</g, '<');  // Replace "< " with "<"
    document.getElementById('textarea').value = str;
  }
  catch (e)
  {
    alert(e.message);
  }
};

function formatJson(indent)
{
  try
  {
    var str = document.getElementById('textarea').value;
    document.getElementById('textarea').value = JSON.stringify(JSON.parse(str), null, indent);
  }
  catch (e)
  {
    alert(e.message);
  }
};
//]]>
</script>
</head>
<body>
  <h2>Inflate/deflate, URL encode/decode</h2>
  <textarea rows="40" cols="120" id="textarea" placeholder="Drop files here or enter text" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off"></textarea>
  <br/><br/>
  <form>
    <input type="checkbox" id="encodeCheckbox" checked="checked" /> URL Encode&nbsp;
    <input type="checkbox" id="deflateCheckbox" checked="checked" /> Deflate&nbsp;
    <input type="checkbox" id="base64Checkbox" checked="checked" /> Base64&nbsp;&nbsp;
    <button onclick="removeLinebreaks(document.getElementById('textarea').value);return false;">Remove linebreaks</button>&nbsp;
    <button onclick="document.getElementById('textarea').value = encodeURIComponent(document.getElementById('textarea').value);return false;">URL Encode</button>&nbsp;
    <button onclick="decodeFromUri();return false;">URL Decode</button>&nbsp;
    <button onclick="encode(document.getElementById('textarea').value);return false;">Encode</button>&nbsp;
    <button onclick="decode(document.getElementById('textarea').value);return false;">Decode</button>&nbsp;
    (<span id="count">0</span> chars)
    <br>
    <button onclick="document.getElementById('textarea').value=escape(document.getElementById('textarea').value);return false;">Escape</button>&nbsp;
    <button onclick="document.getElementById('textarea').value=btoa(document.getElementById('textarea').value);return false;">btoa</button>
    <button onclick="document.getElementById('textarea').value=atob(document.getElementById('textarea').value);return false;">atob</button>
    <button onclick="normalizeXml();return false;">Normalize XML</button>
    <button onclick="formatJson(2);return false;">Format JSON</button>
    <button onclick="formatJson();return false;">Normalize JSON</button>
<script type="text/javascript">
//<![CDATA[
// Enables dropping files
if (window.File != null && window.FileReader != null && window.FileList != null)
{
    function handleDrop(evt)
    {
        evt.stopPropagation();
        evt.preventDefault();

        if (evt.dataTransfer.files.length > 0)
        {
            var file = evt.dataTransfer.files[0];

            var reader = new FileReader();
            reader.onload = function (e)
            {
                evt.target.value = e.target.result;
            };
            reader.readAsText(file);
        }
    };

    function handleDragOver(evt)
    {
        evt.stopPropagation();
        evt.preventDefault();
    };

    // Setup the dnd listeners.
    var textarea = document.getElementById('textarea');

    textarea.addEventListener('dragover', handleDragOver, false);
    textarea.addEventListener('drop', handleDrop, false);
    var span = document.getElementById('count')

	  function updateCount()
	  {
		  span.innerHTML = textarea.value.length;
	  }

    textarea.addEventListener('input', updateCount, false);
}
//]]>
</script>
</form>
</body>
</html>
